#!/usr/bin/env python
# coding:utf-8

__author__ = "SQL-RICE Proyect"

__copyright__ = "Copyright (C) 2012 Daniel Contreras, Jan Gallardo, Alejadro Peña, Jesus Rojas, Gustavo Rubio,"

__license__ = "GPLv3"

__version__ = "0.1"
import cmd
from sql_rice import rules
from sql_rice.utils.common_lambda import do_nothing


class RuleEditor(cmd.Cmd):

    prompt = 'rule:>>'
    intro = ''
    builtins = list(rules.BUILTINS.keys())

    def _add_rule(self, name, val, field):
        if field is None:
            field = rules.Rule(pattern=name)
        validator = rules.Validator.get_by(name=val)
        field.validators.append(validator)
        rules.session.commit()

    def _rem_rule(self, name, val, field):
        if field is None:
            self.stdout.write('no field named %s' % name)
        else:
            validator = rules.Validator.get_by(name=val)
            try:
                field.validators.remove(validator)
                rules.session.commit()
            except ValueError:
                self.stdout.write('rule %s not aplied to %s' % (val, name))

    def _list_rules(self, name, val, field):
        if field is None:
            self.stdout.write('field %s not registred' % name)
        else:
            for v in field.validators:
                self.stdout.write(v.name)
            self.stdout.write('\n')

#FIXME: fails if no 2nd arg provided

    def do_field(self, args):
        '''apply/remove validator to a specific field
        usage: field <name> [add|rem|list] [validator name]
        example: field rut add rut'''
        args = str(args)
        try:
            name, action, validator = args.split()
        except ValueError:
            name, action = args.split()
            validator = None
        field = rules.Rule.get_by(pattern=name)
        switch = {'add': self._add_rule,
                  'rem': self._rem_rule,
                  'list': self._list_rules}
        switch.get(action, do_nothing)(name, validator, field)

    def do_list(self, arg):
        self.stdout.write(str(self.builtins))
        self.stdout.write('\n')

    def do_quit(self, args):
        raise KeyboardInterrupt()

    def emptyline(self):
        pass

    def do_attach(self, filename=''):
        if filename:
            rules.metadata.bind = 'sqlite:///%s' % filename
        else:
            rules.metadata.bind = 'sqlite:///:memory:'
            self.stdout.write('RULEDIT IS WORKING IN VOLATILE MODE\n')
        rules.setup_all(True)
        for v in self.builtins:
            rules.Validator(name=v)
        try:
            rules.session.commit()
        except Exception as e:
            rules.session.rollback()

    def do_create(self, args):
        '''create <name> <from> <params>'''
        command = args.split()
        name = command[0]
        rule = command[1]
        params = dict((x[0], float(x[1]) if x[1].isdigit()
                        else x[1].strip('"'))  for x in
                     (c.split('=') for c in command[2:]))
        v = rules.Validator(name=name, builtin=rule, params=params)
        try:
            rules.session.commit()
        except:
            rules.session.rollback()
            raise
        
    def do_make(self, args):
        '''make name <rules>'''
        command = args.split()
        name = command[0]
        rule = command[1:]
        v = rules.Validator(name=name, simple=False)
        for r in rule:
            v.childs.append(rules.Validator.get_by(name=r))
        try:
            rules.session.commit()
        except:
            rules.session.rollback()
            raise


def main(filename=''):
    interpreter = RuleEditor()
    interpreter.do_attach(filename)
    try:
        interpreter.cmdloop()
    except KeyboardInterrupt:
        print('bye')

if __name__ == '__main__':
    import plac
    plac.call(main)
